/*
 * Copyright 2017 HomeAdvisor, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *
 */

package com.homeadvisor.kafdrop.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Auto configuration for enabling CORS support. Can override behavior with
 * various configs:
 *
 * <ul>
 *    <li>cors.enabled</li>
 *    <li>cors.allowOrigins</li>
 *    <li>cors.allowMethods</li>
 *    <li>cors.maxAge</li>
 *    <li>cors.allowCredentials</li>
 *    <li>cors.allowHeaders</li>
 * </ul>
 * <br/>
 * To disable CORS entirely, set <b>cors.enabled=false</b>. All other configs are
 * just Strings that get used as-is to set the corresponding CORS header.
 */
@Configuration
@ConditionalOnProperty(value = "cors.enabled", matchIfMissing = true)
public class CorsConfiguration
{
   @Value("${cors.allowOrigins:*}")
   private String corsAllowOrigins;

   @Value("${cors.allowMethods:GET,POST,PUT,DELETE}")
   private String corsAllowMethods;

   @Value("${cors.maxAge:3600}")
   private String corsMaxAge;

   @Value("${cors.allowCredentials:true}")
   private String corsAllowCredentials;

   @Value("${cors.allowHeaders:Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization}")
   private String corsAllowHeaders;

   @Bean
   @Order(Ordered.HIGHEST_PRECEDENCE)
   public Filter corsFilter()
   {
      return new Filter()
      {
         @Override
         public void init(FilterConfig filterConfig) throws ServletException
         {}

         @Override
         public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
         {
            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest) req;

            response.setHeader("Access-Control-Allow-Origin", corsAllowOrigins);
            response.setHeader("Access-Control-Allow-Methods", corsAllowMethods);
            response.setHeader("Access-Control-Max-Age", corsMaxAge);
            response.setHeader("Access-Control-Allow-Credentials", corsAllowCredentials);
            response.setHeader("Access-Control-Allow-Headers", corsAllowHeaders);

            if(request.getMethod().equals(HttpMethod.OPTIONS.name()))
            {
               response.setStatus(HttpStatus.NO_CONTENT.value());
            }
            else
            {
               chain.doFilter(req, res);
            }
         }

         @Override
         public void destroy() {}
      };
   }
}
